import os
import sys
from importlib import import_module
from inspect import iscoroutinefunction
from typing import Callable

from bald_spider.settings.settings_manager import SettingsManager

def _get_closest(path='.'):
    path = os.path.abspath(path)
    return path

def _init_env():
    closest = _get_closest()
    if closest:
        project_dir = os.path.dirname(closest)
        sys.path.append(project_dir)

def get_settings(settings = 'settings'):
    _settings = SettingsManager()
    _init_env() # 处理导入多个爬虫脚本可能出现的意外情况
    _settings.set_settings(settings)
    return _settings

"""
    用于实现不同脚本的独立配置参数
"""
def merge_settings(spider,settings):
    if hasattr(spider,'custom_settings'):
        for setting in getattr(spider,'custom_settings'):
            settings.update_settings(setting)

def load_class(_path):
    if not isinstance(_path, str):
        if callable(_path):
            return _path
        else:
            raise TypeError(f"args expected str or callable, got {type(_path)!r}")
    module,name = _path.rsplit(".",1)
    mod = import_module(module)
    try:
        cls = getattr(mod, name)
    except AttributeError:
        raise NameError(f"Module {module!r} doesn't define any object named {name!r}")
    return cls

async def common_call(func:Callable, *args, **kwargs):
    if iscoroutinefunction(func):
        return await func(*args, **kwargs)
    else:
        return func(*args, **kwargs)